//
//  WXPKAnimationView.m
//  ParentsCommunity
//
//  Created by tianlong on 2018/5/2.
//  Copyright © 2018年 XES. All rights reserved.
//

#import "WXPKAnimationView.h"
//#import "LiveNewPKUtil.h"

#define CoverViewAlpha 0.6

@interface WXPKAnimationView ()<CAAnimationDelegate>
@property (copy, nonatomic) void (^throwCompletion)(BOOL isFinished);
@property (weak, nonatomic) UIImageView *coverView;
@property (assign, nonatomic) NSInteger playedCount;
@property (assign, nonatomic) BOOL endLoop;
@property (strong, nonatomic) NSMutableArray *throwViews;
@property (strong, nonatomic) CADisplayLink *displayLink;
@end

@implementation WXPKAnimationView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.playedCount = 0;
    }
    return self;
}

- (NSMutableArray *)throwViews{
    if (!_throwViews) {
        _throwViews = [NSMutableArray array];
    }
    return _throwViews;
}

- (WXPKLOTAnimationView *)playView{
    if (!_playView) {
        _playView = [[WXPKLOTAnimationView alloc] init];
        [self insertSubview:_playView atIndex:0];
        [_playView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.top.bottom.right.offset(0);
        }];
    }
    return _playView;
}

#pragma mark - 核心代码
- (void)playAnimationWithJson:(NSString *)json
                        speed:(CGFloat)speed
                  repeatCount:(NSInteger)repeatCount
            willBeginPlayTodo:(void (^)(void))playTodo
                   completion:(void (^)(BOOL finished))completion {
    if (json) {
        
        __weak typeof(self)selfWeak = self;
        self.animationJson = json;
        [self.playView setAnimationNamed:self.animationJson];
        [self.playView setAnimationSpeed:speed];
        [self.playView logHierarchyKeypaths];
        [self.playView forceDrawingUpdate];
        self.playView.loopAnimation = NO;
        [self play];
        
        [self.playView setCompletionBlock:^(BOOL animationFinished) {
            
            selfWeak.playedCount += 1;
            [selfWeak stopDisplayLink];
            
            if (repeatCount <= 1 ||
                selfWeak.playedCount == repeatCount) {
                selfWeak.playedCount = 0;
                if (completion) {
                    completion(YES);
                }
                return;
            }else {
                if (!selfWeak.endLoop) {
                    [selfWeak playAnimationWithJson:json speed:speed repeatCount:repeatCount willBeginPlayTodo:playTodo completion:completion];
                }
            }
        }];
        
        if (!_backgroundImageView) {
            UIImageView *backgroundImageView = [[UIImageView alloc] init];
            self.backgroundImageView = backgroundImageView;
            [self insertSubview:self.backgroundImageView belowSubview:self.playView];
            [self.backgroundImageView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.top.left.bottom.right.offset(0);
            }];
        }
        
        if (!_coverView) {
            UIImageView *coverView = [[UIImageView alloc] init];
            self.coverView = coverView;
            self.coverView.alpha = CoverViewAlpha;
            self.coverView.hidden = YES;
            self.coverView.backgroundColor = [UIColor blackColor];
            [self.backgroundImageView addSubview:self.coverView];
            [self.coverView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.top.left.bottom.right.offset(0);
            }];
        }
        
        // 特殊处理下背景和遮盖
        if ([json rangeOfString:@"fendui_1"].location != NSNotFound ||
            [json rangeOfString:@"fendui_2"].location != NSNotFound ||
            [json rangeOfString:@"fendui_3"].location != NSNotFound) {
            self.backgroundImageView.image = [UIImage imageNamed:PK_AnimationBackgroundImage];
            self.coverView.hidden = YES;
        }else if ([json rangeOfString:@"fendui_4"].location != NSNotFound){
            self.backgroundImageView.image = [UIImage imageNamed:PK_AnimationBackgroundImage];
            self.coverView.hidden = YES;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                selfWeak.coverView.hidden = NO;
                selfWeak.coverView.alpha = 0;
                [UIView animateWithDuration:.5 animations:^{
                    selfWeak.coverView.alpha = CoverViewAlpha;
                }];
            });
        }else if ([json rangeOfString:@"fendui_list"].location != NSNotFound ||
                  [json rangeOfString:@"golden_shake"].location != NSNotFound ||
                  [json rangeOfString:@"sliver_shake"].location != NSNotFound ||
                  [json rangeOfString:@"golden_open"].location != NSNotFound ||
                  [json rangeOfString:@"sliver_open"].location != NSNotFound ||
                  [json rangeOfString:@"gold_list"].location != NSNotFound ||
                  [json rangeOfString:@"sliver_list"].location != NSNotFound ) {
            
            self.backgroundImageView.image = [UIImage imageNamed:PK_AnimationBackgroundImage];
            self.coverView.hidden = NO;
        }else if ([json rangeOfString:@"pengzhuang2"].location != NSNotFound ||
                  [json rangeOfString:@"pk_win"].location != NSNotFound ||
                  [json rangeOfString:@"pk_tie"].location != NSNotFound ||
                  [json rangeOfString:@"pk_lose"].location != NSNotFound ||
                  [json rangeOfString:@"pk_superstar"].location != NSNotFound ||
                  [json rangeOfString:@"pk_darkhorse"].location != NSNotFound ||
                  [json rangeOfString:@"pk_contristar"].location != NSNotFound) {
            self.backgroundImageView.image = [UIImage imageNamed:PK_AnimationFivePointedStarBackgroundImage];
            self.coverView.hidden = YES;
        }else {
            self.backgroundImageView.image = nil;
            self.coverView.hidden = NO;
        }
        
        if (playTodo) {
            playTodo();
        }
    }
    
    if (!_closeBtn) {
        UIButton *btn = [[UIButton alloc] init];
        [btn setImage:[UIImage imageNamed:@"zdpk_icon_close_normal"] forState:UIControlStateNormal];
        [btn setImage:[UIImage imageNamed:@"zdpk_icon_close_press"] forState:UIControlStateNormal];
        [btn addTarget:self action:@selector(clickedCloseBtn) forControlEvents:UIControlEventTouchDown];
        btn.hidden = YES;
        [self addSubview:btn];
        self.closeBtn = btn;
        [btn mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(@(11));
            make.right.mas_equalTo(@(-13));
            make.width.height.offset(37);
        }];
    }
}

- (void)clickedCloseBtn {
    if (self.clickedCloseBlock) {
        self.clickedCloseBlock();
    }
}

- (void)playAnimationWithJson:(NSString *)json
                        speed:(CGFloat)speed
                  repeatCount:(NSInteger)repeatCount
                   completion:(void (^)(BOOL finished))completion {
    [self playAnimationWithJson:json speed:speed repeatCount:repeatCount willBeginPlayTodo:nil completion:completion];
}

- (void)play{
    self.userInteractionEnabled = YES;
    self.isAnimating = YES;
    self.endLoop = NO;
    [self.playView play];
    [self startDisplayLink];
}

- (void)pause{
    [self.playView pause];
    [self stopDisplayLink];
}

- (void)stop{
    
    self.isAnimating = NO;
    self.endLoop = YES;
    self.playedCount = 0;
    
    [self.playView stop];
    [self stopDisplayLink];
    
    [self.playView removeFromSuperview];
    [self.coverView removeFromSuperview];
    [self.backgroundImageView removeFromSuperview];
 
    _playView = nil;
    _coverView = nil;
    _backgroundImageView = nil;
    self.userInteractionEnabled = NO;
}

#pragma mark - 弹框类动画视图
- (WXPKAnimationAlert *)showAnimationAlertWithJsonName:(NSString *)json
                                                 speed:(float)speed
                                             alertSize:(CGSize)alertSize
                                                inView:(UIView *)inView
                                            completion:(void (^)(BOOL isFinished))completion {

    WXPKAnimationAlert *alert = [[WXPKAnimationAlert alloc] init];
    [inView addSubview:alert];
    
    __weak typeof(self)selfWeak = self;
    [alert mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(inView.mas_centerX);
        make.centerY.equalTo(inView.mas_centerY);
        make.width.offset([selfWeak pptW]);
        make.height.offset([selfWeak pptH]);
        //make.left.top.bottom.right.offset(0);
    }];
    
    [alert setAnimationNamed:json];
    [alert setAnimationSpeed:speed];
    [alert logHierarchyKeypaths];
    [alert forceDrawingUpdate];
    alert.loopAnimation = NO;
    [alert setCompletionBlock:^(BOOL animationFinished) {
        if (completion) {
            completion(animationFinished);
        }
    }];
    [alert play];
    return alert;
}

#pragma mark - 绑定视图到指定路径的图层
/**
 绑定视图到动画指定路径的图层上
 */
- (void)bindingUIView:(UIView *)view
           forKeyPath:(NSString *)keyPath
            imageName:(NSString *)imageName{
    LOTKeypath *keypath = [LOTKeypath keypathWithString:keyPath];
    if (keypath) {
        if (view) {
            [self.playView addSubview:view toKeypathLayer:keypath];
            CGRect frame = [self fetchImageEntityInfile:self.animationJson imageName:imageName];
            [view mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.offset(frame.origin.x);
                make.top.offset(frame.origin.y);
                make.width.offset(frame.size.width);
                make.height.offset(frame.size.height);
            }];
        }
    }
}

- (CGRect)fetchImageEntityInfile:(NSString *)fileName imageName:(NSString *)imageName{
    NSError *error;
    NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"json"];
    NSData *jsonData = [[NSData alloc] initWithContentsOfFile:filePath];
    
    if (@available(iOS 9.0, *)) {
        if (!jsonData) {
            jsonData = [[NSDataAsset alloc] initWithName:fileName].data;
        }
    }
    //解析json 文件 生成字典
    NSDictionary  *jsonObject = jsonData ? [NSJSONSerialization JSONObjectWithData:jsonData
                                                                           options:0 error:&error] : nil;
    CGRect rect = CGRectZero;
    if (jsonObject && !error) {
        
        //assets 中存在着元素的基本信息， h， w， nm  id
        NSArray *assets = [jsonObject objectForKey:@"assets"];
        
        for (int i = 0; i <assets.count; i++) {
            /*
             assetsDict =   {
             h = 53;
             id = "image_0";
             p = "img_4.png";
             u = "images/";
             w = 52;
             }
             */
            NSDictionary *assetsDict = [assets objectAtIndex:i];
            
            if (assetsDict && [assetsDict isKindOfClass:[NSDictionary class]]) {
                
                NSString *p = [assetsDict objectForKey:@"p"];
                if (p) {
                    
                    if ([p isEqualToString:imageName]) {
                        NSString *widthStr = [assetsDict objectForKey:@"w"];
                        NSString *heightStr = [assetsDict objectForKey:@"h"];
                        if (widthStr && heightStr) {
                            rect.size.width = widthStr.floatValue;
                            rect.size.height = heightStr.floatValue;
                        }
                        break;
                    }
                }
            }
        }
    }
    return rect;
}

#pragma mark - 通过json获取动画layer层的数组
/**
 图层相关信息,图层名称，图片名称等
 {
 "nm": "Pre-comp10",
 "fr": 60,
 "assets": [],
 "layers": [],
 "h": 1440,
 "markers": [],
 "v": "5.1.8",
 "ddd": 0,
 "w": 1920,
 "ip": 0,
 "op": 70
 }
 */
- (NSDictionary *)getAnimationInfoWithJsonName:(NSString *)jsonName {
    NSError *error;
    NSString *filePath = [[NSBundle mainBundle] pathForResource:jsonName ofType:@"json"];
    NSData *jsonData = [[NSData alloc] initWithContentsOfFile:filePath];
    
    if (@available(iOS 9.0, *)) {
        if (!jsonData) {
            jsonData = [[NSDataAsset alloc] initWithName:jsonName].data;
        }
    }
    NSDictionary *jsonObject = jsonData ? [NSJSONSerialization JSONObjectWithData:jsonData
                                                                          options:0 error:&error] : nil;
    return jsonObject;
}

#pragma mark - 动画播放过程中实时调用
- (void)startDisplayLink{
    self.displayLink = [CADisplayLink displayLinkWithTarget:self
                                                   selector:@selector(handleDisplayLink:)];
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop]
                           forMode:NSDefaultRunLoopMode];
    
}

- (void)handleDisplayLink:(CADisplayLink *)displayLink{
//    if ([self.delegate respondsToSelector:@selector(animationPlaying:animationJsonName:)]) {
//        [self.delegate animationPlaying:self.playView animationJsonName:self.animationJson];
//    }
}

- (void)stopDisplayLink{
    [self.displayLink invalidate];
    self.displayLink = nil;
}

#pragma mark - 转换动画中指定元素的layer的frame到animtionView的layer上
/**
 转换动画中指定元素的layer的frame到animtionView的layer上
 方便添加自定义控件，以及通过动画的实时方法来达到自定义控件与动画中指定元素layer的frame保持一致，从而达到自定义控件与其动画效果一致，并且可以交互。
 @param elementLayer 必须与动画中的图层绑定，例如：与[self.animationView addSubview:elementLayerInView toKeypathLayer:keypath] 这个方法中的keypath绑定
 */
- (CGRect)convertElementLayerFrameToAnimationLayer:(CALayer *)elementLayer{
    [self.playView layoutIfNeeded];
    CGRect convertF = [elementLayer convertRect:elementLayer.frame toLayer:self.playView.layer];
    return convertF;
}


#pragma mark - 抛物线函数
- (void)throwObjectView:(UIView *)startView
                     to:(UIView *)endView
                 height:(CGFloat)height
               duration:(CGFloat)duration
             completion:(void (^)(BOOL isFinished))completion {
    
//    [LiveNewPKUtil throwAnimateFromView:startView endView:endView value:0 duration:duration completion:^(BOOL finished) {
//        if (completion) {
//            completion(YES);
//        }
//    }];
    
    /*
    // 将坐标系都转移到window上
    UIWindow *keyWindow = [UIApplication sharedApplication].delegate.window;
    CGPoint start = [startView.superview ? startView.superview : keyWindow convertPoint:startView.center toView:keyWindow];
    CGPoint end = [endView.superview ? endView.superview : keyWindow convertPoint:endView.center toView:keyWindow];
    
    CGRect startF = [startView.superview ? startView.superview : keyWindow convertRect:startView.frame toView:keyWindow];
    CGRect endF = [endView.superview ? endView.superview : keyWindow convertRect:endView.frame toView:keyWindow];
    
    // 缩放系数
    CGFloat scale = 1;
    if (endView.width > 0 && startView.width > 0) {
        scale = startView.width > endView.width ? endView.width/startView.width : startView.width/endView.width;
    }
    // 生成一个一模一样的开始view
    UIImageView *win_startView = [[UIImageView alloc] init];
    if ([startView isKindOfClass:[UIImageView class]]) {
        win_startView.image = [(UIImageView *)startView image];
    }
    win_startView.frame = startF;
    [keyWindow addSubview:win_startView];
    [self.throwViews addObjectSafe:win_startView];
    
    // 生成一个一模一样的结束view
    UIImageView *win_endView = [[UIImageView alloc] init];
    if ([endView isKindOfClass:[UIImageView class]]) {
        win_endView.image = [(UIImageView *)endView image];
    }
    win_endView.frame = endF;
    [keyWindow addSubview:win_endView];
    [self.throwViews addObjectSafe:win_endView];
    
    //初始化抛物线的路径
    CGMutablePathRef path = CGPathCreateMutable();
    CGFloat cpx = (start.x + end.x) / 2;
    CGFloat cpy = height;
    CGPathMoveToPoint(path, NULL, start.x, start.y);
    CGPathAddQuadCurveToPoint(path, NULL, cpx, cpy, end.x, end.y);
    
    // 位移
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.path = path;
    
    // 缩放
    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    scaleAnimation.autoreverses = YES;
    scaleAnimation.toValue = [NSNumber numberWithFloat:scale];
    
    // 旋转
    CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    scaleAnimation.fromValue = [NSNumber numberWithFloat:1];
    rotateAnimation.toValue = [NSNumber numberWithFloat:6.0 * M_PI];
    rotateAnimation.duration = 0.8;
    
    //透明度变化
    CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAnimation.fromValue = [NSNumber numberWithFloat:1];
    opacityAnimation.toValue = [NSNumber numberWithFloat:0.0];
    
    
    CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
    groupAnimation.delegate = self;
    groupAnimation.repeatCount = 1;
    groupAnimation.duration = duration;
    groupAnimation.speed = 1;
    groupAnimation.removedOnCompletion = NO;
    groupAnimation.fillMode = kCAFillModeForwards;
    
    //组动画
    //groupAnimation.animations = @[scaleAnimation,animation,rotateAnimation];
    groupAnimation.animations = @[animation,scaleAnimation,opacityAnimation];
    [win_startView.layer addAnimation:groupAnimation forKey:nil];
    
    self.throwCompletion = completion;
    */
}

- (void)throwPKBoxView:(UIView *)startView
                    to:(UIView *)endView
                height:(CGFloat)height
              duration:(CGFloat)duration
            completion:(void (^)(BOOL isFinished))completion {
    
    // 将坐标系都转移到window上
    UIWindow *keyWindow = [UIApplication sharedApplication].delegate.window;
    CGPoint start = [startView.superview ? startView.superview : keyWindow convertPoint:startView.center toView:keyWindow];
    CGPoint end = [endView.superview ? endView.superview : keyWindow convertPoint:endView.center toView:keyWindow];
    
    // 缩放系数
    CGFloat scale = 1;
    if (endView.width > 0 && startView.width > 0) {
        scale = startView.width > endView.width ? endView.width/startView.width : startView.width/endView.width;
    }
    
    //初始化抛物线的路径
    CGMutablePathRef path = CGPathCreateMutable();
    CGFloat cpx = (start.x + end.x) / 2;
    CGFloat cpy = height;
    CGPathMoveToPoint(path, NULL, start.x, start.y);
    CGPathAddQuadCurveToPoint(path, NULL, cpx, cpy, end.x, end.y);
    
    // 位移
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.path = path;
    
    // 缩放
    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    scaleAnimation.autoreverses = YES;
    scaleAnimation.toValue = [NSNumber numberWithFloat:scale];
    
    // 旋转
    CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    scaleAnimation.fromValue = [NSNumber numberWithFloat:1];
    rotateAnimation.toValue = [NSNumber numberWithFloat:6.0 * M_PI];
    rotateAnimation.duration = 0.8;
    
    CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
    groupAnimation.delegate = self;
    groupAnimation.repeatCount = 1;
    groupAnimation.duration = duration;
    groupAnimation.removedOnCompletion = NO;
    groupAnimation.fillMode = kCAFillModeForwards;
    
    //组动画
    groupAnimation.animations = @[animation,scaleAnimation];
    [startView.layer addAnimation:groupAnimation forKey:nil];
    
    self.throwCompletion = completion;
}

#pragma mark - CAAnimationDelegate
- (void)animationDidStart:(CAAnimation *)anim {}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    if (flag) {
        if (self.throwCompletion) {
            self.throwCompletion(flag);
        }
        
        for (UIView *obj in self.throwViews) {
            [obj removeFromSuperview];
        }
        
        [self.throwViews removeAllObjects];
        
        self.throwCompletion = nil;
    }
}

- (CGFloat)pptW {
    return [LiveSizeConfig getPPTWidth];
}

- (CGFloat)pptH {
    return [LiveSizeConfig getPPTHeight];
}

- (CGFloat)pptLeft {
    return [LiveSizeConfig getHorizontalSpace];
}

- (CGFloat)pptTop {
    return [LiveSizeConfig getVerticalSpace];
}

@end
